package main

import (
	"database/sql"
	_"github.com/go-sql-driver/mysql"
	"time"
)

const LOG_STATUS_SUCC = 1
const LOG_STATUS_FAIL = 2

func GetCronJobs(product_id string) (map[int]map[string]string) {
	query_sql := "select * from task_timed where project_id = ? and status = 1 and machine_id = "+DockerId //可执行的任务
	ret := queryMultiple(query_sql, product_id)
	return  ret
}

func GetAlarmTaskLog()(map[int]map[string]string){
	query_sql := "select * from task_log where status <> 1 and alarm_status = 1 order by id"
	ret := queryMultiple(query_sql)
	return  ret
}

func getJobByTaskId(taskId string)(map[string]string){
	query_sql := "select * from task_timed where id = "+taskId + " limit 1" //项目列表
	ret := querySingle(query_sql)
	return  ret
}
func getMonitorJobAlarmMessageByMonitorId(monitorId string)(map[string]string){
	query_sql := "select * from monitor_job_alarm_message where monitor_id = "+monitorId + " limit 1" //项目列表
	ret := querySingle(query_sql)
	return  ret
}
func getTaskAlarmsByTaskId(taskId string)(map[int]map[string]string){
	query_sql := "select * from task_alarm where task_id = "+taskId //项目列表
	ret := queryMultiple(query_sql)
	return  ret
}
func getMonitorJobAlarmsByMonitorId(MonitorId string)(map[int]map[string]string){
	query_sql := "select * from monitor_job_alarm where monitor_id = "+MonitorId+" and status = 1" //项目列表
	ret := queryMultiple(query_sql)
	return  ret
}


func GetAllProjects() (map[int]map[string]string){
	query_sql := "select * from task_project" //项目列表
	ret := queryMultiple(query_sql)
	return  ret
}

func GetAllMonitorList() (map[int]map[string]string){
	query_sql := "select * from monitor_job_list"
	ret := queryMultiple(query_sql)
	return ret
}

func GetAllCommands()(map[int]map[string]string){
	query_sql := "select * from task_command where status = 1" //项目列表
	ret := queryMultiple(query_sql)
	return  ret
}

func JobStart(job map[string]string) int64 {
	//写入任务执行日志
	insert_sql := "insert into task_log (project_id, task_id, machine_id, exec_start_time) values (?, ?, ?, ?)"
	now_time := time.Now().Format("2006-01-02 15:04:05")
	run_id := insert(insert_sql, job["project_id"], job["id"], DockerId, now_time)

	return run_id
}

func JobEnd(run_id int64, succ bool, export string) bool{
	if(len(export) > 65535){
		export = export[:65530] + "..."
	}
	now_time := time.Now().Format("2006-01-02 15:04:05")
	var log_status int
	if(succ){
		log_status  = LOG_STATUS_SUCC
	}else{
		log_status = LOG_STATUS_FAIL
	}
	//更新执行日志
	update_sql := "update task_log set status = ?, exec_export = ?, exec_end_time = ? where id = ?"
	update(update_sql, log_status, export, now_time, run_id)
	//如果为一次性任务 则更新他的执行状态
	return true
}


func AlarmEnd(LogId string) bool{
	//更新执行日志
	update_sql := "update task_log set alarm_status = 2 where id = ?"
	update(update_sql, LogId)
	//如果为一次性任务 则更新他的执行状态
	return true
}

func queryMultiple(query_sql string, args... interface{}) (map[int]map[string]string) {
	//查询数据库
	db := connect("read")
	rows, err := db.Query(query_sql, args...)
	defer db.Close()
	if (err != nil) {
		panic(err.Error())
	}

	//构造scanArgs、values两个数组，scanArgs的每个值指向values相应值的地址
	columns, _ := rows.Columns()
	scanArgs := make([]interface{}, len(columns))
	values := make([][]byte, len(columns))
	for i := range values {
		scanArgs[i] = &values[i]
	}

	//最后得到的map
	i := 0
	ret := make(map[int]map[string]string)
	for rows.Next() {
		err = rows.Scan(scanArgs...);
		record := make(map[string]string) //每行数据
		for k, v := range values { //每行数据是放在values里面，现在把它挪到row里
			record[columns[k]] = string(v)
		}
		ret[i] = record //装入结果集中
		i++
	}

	return ret
}

func querySingle(query_sql string, args... interface{}) (map[string]string) {
	//查询数据库
	db := connect("read")
	rows, err := db.Query(query_sql, args...)
	defer db.Close()
	if (err != nil) {
		panic(err.Error())
	}

	//构造scanArgs、values两个数组，scanArgs的每个值指向values相应值的地址
	columns, _ := rows.Columns()
	scanArgs := make([]interface{}, len(columns))
	values := make([][]byte, len(columns))
	for i := range values {
		scanArgs[i] = &values[i]
	}
	rows.Next()
	err = rows.Scan(scanArgs...);
	record := make(map[string]string) //每行数据
	for k, v := range values { //每行数据是放在values里面，现在把它挪到row里
		record[columns[k]] = string(v)
	}

	return record
}

func insert(insert_sql string, args... interface{}) int64{
	db := connect("write")
	res, err := db.Exec(insert_sql, args...)
	defer db.Close()
	if (err != nil) {
		panic(err.Error())
	}
	id, _ := res.LastInsertId()
	return id
}

func update(update_sql string, args... interface{}) bool{
	db := connect("write")
	_, err := db.Exec(update_sql, args...)
	defer db.Close()
	if (err != nil) {
		panic(err.Error())
	}
	return true
}


func connect(action string) (*sql.DB) {
	config := GetConfig()
	dsn := ""
	if type =="read" {
		dsn = config.Mysql.Read.Username + ":" + config.Mysql.Read.Password + "@tcp(" + config.Mysql.Read.Host + ")/" + config.Mysql.Read.Dbname + "?charset=" + config.Mysql.Read.Charset
	} else {
		dsn = config.Mysql.Write.Username + ":" + config.Mysql.Write.Password + "@tcp(" + config.Mysql.Write.Host + ")/" + config.Mysql.Write.Dbname + "?charset=" + config.Mysql.Write.Charset
	}
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(err.Error())
	}
	return db
}


